package com.zte.claa.inficombo.csa.app.service.mqttproxy.sswdevtype;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.zte.claa.inficombo.csa.app.config.MQTTParaConfig;
import com.zte.claa.inficombo.csa.app.model.dev.DevBase;
import com.zte.claa.inficombo.csa.app.model.dev.ResourceShadow;
import com.zte.claa.inficombo.csa.app.service.csa.impl.BaseCacheManager;
import com.zte.claa.inficombo.csa.app.service.mqttproxy.IMqttProxyService;
import com.zte.claa.inficombo.csa.app.service.mqttproxy.MqttUpdataParser;
import com.zte.claa.inficombo.csa.app.service.mqttproxy.mqttclient.MqttPubSubClient;
import com.zte.claa.inficombo.csa.app.service.rptparse.ParserContainer;
import com.zte.claa.inficombo.csa.app.util.JsonUtils;

@Service
public class SSWMqttProxyService implements IMqttProxyService, InitializingBean, DisposableBean {
	// logger
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private BaseCacheManager cacheManager;
	
	@Autowired
	private ParserContainer parserContainer;
		
	@Autowired
	private MQTTParaConfig mqttpara;
	
	@Value("${csa.mqtt.sswdevtp.cmd.topics}")
	private String cmdTopic;
	
	// csa.mqtt.sswdevtp.rpt.topics=jecinfo/liusu,jecinfo/yali,jecinfo/liuliang
	@Value("${csa.mqtt.sswdevtp.rpt.topics}")
	private String rptTopics;
	
	// 对应的设备类型（主要用于命令下发）
	@Value("${csa.mqtt.sswdevtp.devtypes}")
	private String supportDevtypes;
	
	// 数据上报消息主题.
	private String[] reportTopicArr;
	
	// 支撑的设备类型.
	private String[] supportDetypeArr;
	
	// mqtt客户端对象.
	private MqttPubSubClient mqttClient = null;
	
	// 上报数据解析...
	private MqttUpdataParser updataParser = null;
	
	@Override
	public void afterPropertiesSet() throws Exception {
		try{
			if(!this.mqttpara.checkSwitchIsOn()){
				logger.warn("MQTT API is configured as [OFF]!");
				return;
			}
			this.reInitService();
		}catch(Exception e){
			logger.error("SSWMqttProxyService init failed!", e);
		}
	}
	
	@Override
	public void destroy() throws Exception {
		if(this.mqttClient != null){
			this.mqttClient.destroy();
		}
		this.mqttClient = null;
	}
	
	// 重新初始化.
	public void reInitService() throws Exception{
		if(this.mqttClient != null){
			this.mqttClient.destroy();
		}
		this.updataParser = new MqttUpdataParser(this.parserContainer);
		if(this.supportDevtypes != null){
			this.supportDetypeArr = this.supportDevtypes.trim().split(",");
		}
		this.reportTopicArr = this.rptTopics.trim().split(",");			
		this.mqttClient = new MqttPubSubClient(this.mqttpara.getClientidprefix(), 
				               this.reportTopicArr, this.cmdTopic, this.mqttpara, this);
	}

	@Override
	public Set<String> getSupportDevtypes() {
		Set<String> devtpSet = new HashSet<String>();
		if(this.supportDetypeArr != null){
			for(String devtp : this.supportDetypeArr){
				devtpSet.add(devtp);
			}
		}		
		return devtpSet;
	}

	/**
	 * 数据上报样例：
	 * "SN":"Y1721013","FW":"1.1","EC":0,"LO":"12046.2633","LA":"3045.8481","DT":"+038","BV":12.1,"RSSI":"25","TIME":1591061400,"DATA":[2.236,2.215,2.247,2.241,2.270,2.241,2.276,2.289,2.243,2.253,2.249,2.266,2.291,2.262,2.266,2.276,2.300,2.298,2.276,2.300,2.300,2.331,2.306,2.304,2.283,2.260,2.285,2.279,2.281,2.304]
	 */
	@Override
	public void onDataReport(String topic, MqttMessage msg) {
		logger.info("Begin process message from tpoic [{}]: {}", topic, msg);
		try{
			this.parseReportData(msg);
			logger.info("Process msg ok: "+msg);
		}catch(Exception e){
			logger.error("process msg failed: "+msg, e);
		}
	}

	@Override
	public int sendControlCmd(String cmd) throws Exception {
		// TODO... 需要从CSA的命令入口处进行设备类型和下发出口区分，然后调用JS插件进行命令构建，最后调用此处下发.
		
		this.mqttClient.sendCmdData(cmd);
		return 0;
	}
	
	// 解析上报数据...
	private void parseReportData(MqttMessage msg) throws Exception {
		String data = new String(msg.getPayload(), this.mqttpara.getCharset());
		String s = data;
		if(!s.startsWith("{")){
			s = "{"+s;
		}
		if(!s.endsWith("}")){
			s = s +"}";
		}
		JSONObject json = new JSONObject(s);
		String devEui = JsonUtils.getJsonAttrVal(json, "SN", null);
		if(devEui == null){
			logger.error("Invalid message data (NOT exist SN field).");
			return;
		}
		ResourceShadow resShadow = this.cacheManager.getRes(devEui);
		if(resShadow == null){
			logger.error("Resshadow instance NOT exist: "+devEui);
			return;
		}
		DevBase dev = this.transferRes(resShadow);
		this.updataParser.parseUpRptData(data, dev);
	}

	// 将resshadow对象转换为devbase
	private DevBase transferRes(ResourceShadow res) {
		DevBase dev = new DevBase();
		dev.setDevEui(res.getResid());
		dev.setDevType(res.getRestype());
		dev.setDevName(res.getResname());
		dev.setAppEui("00");
		dev.setProjectId(res.getProjectid());
		dev.setDevflag((byte)3);
		dev.setNetworktype((byte)2);		
		return dev;
	}
}
